//----------------------------------------------------------------------------------------
// patterns & practices - Smart Client Software Factory - Guidance Package
//
using System;
using System.Windows.Forms;
using System.Configuration;
using System.ComponentModel;
using Metro.SmartClient.Infrastructure.Interface;
using Metro.SmartClient.Infrastructure.Shell.Constants;
using Microsoft.Practices.CompositeUI.EventBroker;
using Microsoft.Practices.CompositeUI;
using Microsoft.Practices.CompositeUI.Services;
using Microsoft.Practices.ObjectBuilder;
using System.Collections.Generic;

namespace Metro.SmartClient.Infrastructure.Shell
{
    /// <summary>
    /// Main application shell view.
    /// </summary>
    public partial class ShellForm : Form
    {
        [EventPublication(EventTopicNames.LoadOrders, PublicationScope.Global)]
        public event EventHandler<EventArgs<List<Metro.Admin.BusinessEntities.Order>>> LoadOrdersEvent;
        [EventPublication(EventTopicNames.StatusUpdate, PublicationScope.Global)]
        public event EventHandler<EventArgs<Metro.Admin.BusinessEntities.Status>> StatusUpdate;
        [EventPublication(EventTopicNames.LoadStats, PublicationScope.Global)]
        public event EventHandler<EventArgs<Metro.Admin.BusinessEntities.Status>> LoadStats;
        private WorkItem localWorkitem;
        private ServiceClient svcClient;
        private delegate void CloseResponse();

        public ShellForm([ServiceDependency] WorkItem workItem)
        {
            InitializeComponent();

            this.Text = WorkspaceNames.ShellMainWindow;
            this.Icon = Metro.SmartClient.Infrastructure.Shell.Properties.Resources.coin;
            leftWorkspace.Name = WorkspaceNames.LeftWorkspace;
            rightWorkspace.Name = WorkspaceNames.RightWorkspace;
            bottomWorkSpace.Name = WorkspaceNames.BottomWorkspace;
            this.localWorkitem = workItem; 
        }

        [ServiceDependency]
        public WorkItem WorkItem
        {
            get { return localWorkitem; }
            set { localWorkitem = value; }
        }

        internal StatusStrip MainStatusStrip
        {
            get { return bottomStatusStrip; }
        }

        internal StatusStrip ParamStatusStrip
        {
            get { return paramStatusStrip; }
        }

        internal ToolStrip MainToolbarStrip
        {
            get { return toolStrip; }
        }

        [EventSubscription(EventTopicNames.StatusUpdate, ThreadOption.UserInterface)]
        public void StatusUpdateHandler(object sender, EventArgs<Metro.Admin.BusinessEntities.Status> status)
        {
            statusLabel.Text = status.Data.State;

            if (status.Data.State.Equals(CommandNames.ConnectStatus))
                statusLabel.Image = Metro.SmartClient.Infrastructure.Shell.Properties.Resources.connect;
            if (status.Data.State.Equals(CommandNames.DisconnectStatus))
                statusLabel.Image = Metro.SmartClient.Infrastructure.Shell.Properties.Resources.disconnect;

            userStatusLabel.Text = "Usuario: " + status.Data.User;
            customerStatusLabel.Text = "Cliente: " + status.Data.Customer;
            marketStatusLabel.Text = "Mercado: " +  status.Data.Market;
            pricesStatusLabel.Text = "Rango de Precios: " +  status.Data.Prices;
            amountStatusLabel.Text = "Rango de Montos: " + status.Data.Amounts;    

        }

        private void OnFileExit(object sender, EventArgs e)
        {
            Close();
        }

        private void ShellForm_Load(object sender, EventArgs e)
        {
            try 
            {
                this.LoadShell(); 
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "ShellForm_Load", MessageBoxButtons.OK, MessageBoxIcon.Warning);  
            }
        }

        private void LoadShell()
        {
            try
            {
                Metro.Admin.BusinessEntities.User user = WorkItem.Items.Get<Metro.Admin.BusinessEntities.User>("UserSession");
                
                Metro.Admin.BusinessEntities.Company company = WorkItem.Items.Get<Metro.Admin.BusinessEntities.Company>("globalCompany");

                if (user != null && company != null)
                {
                    svcClient = WorkItem.RootWorkItem.Items.AddNew<ServiceClient>("svcClient");
                    svcClient.Link();

                    if (!company.PlatformSuspend)
                    {

                        Metro.Admin.BusinessEntities.Status status = new Metro.Admin.BusinessEntities.Status();
                        status.User = user.Login;
                        status.Customer = user.CustomerName;
                        status.Market = company.GetCurrentMarket().ToString();
                        status.State = CommandNames.ConnectStatus;
                        status.Prices = company.MinimalPrice.ToString("C") + " - " + company.MaximalPrice.ToString("C");
                        status.Amounts = company.MinimalAmount.ToString("USD #,#") + " - " + company.MaximalAmount.ToString("USD #,#");

                        status.UserContext = user;
                        status.CompanyContext = company;  

                        OnStatusUpdate(new EventArgs<Metro.Admin.BusinessEntities.Status>(status));

                        OnLoadStats(new EventArgs<Metro.Admin.BusinessEntities.Status>(status));
                    }
                    else 
                    {
                        MessageBox.Show("La plataforma esta suspendida", "LoadShell", MessageBoxButtons.OK, MessageBoxIcon.Information);  
                        this.Close(); 
                    }
                }

                List<Metro.Admin.BusinessEntities.Order> orders = WorkItem.Items.Get<List<Metro.Admin.BusinessEntities.Order>>("ordersLoaded");

                if(orders != null)
                    OnLoadOrdersEvent(new EventArgs<List<Metro.Admin.BusinessEntities.Order>>(orders));
            }
            catch (Exception ex)
            { 
              throw ex; 
            }
        }

        protected virtual void OnStatusUpdate(EventArgs<Metro.Admin.BusinessEntities.Status> eventArgs)
        {
            if (StatusUpdate != null)
            {
                StatusUpdate(this, eventArgs);
            }
        }

        protected virtual void OnLoadStats(EventArgs<Metro.Admin.BusinessEntities.Status> eventArgs)
        {
            if (LoadStats != null)
            {
                LoadStats(this, eventArgs);
            }
        }

        protected virtual void OnLoadOrdersEvent(EventArgs<List<Metro.Admin.BusinessEntities.Order>> eventArgs)
        {
            if (LoadOrdersEvent != null)
            {
                LoadOrdersEvent(this, eventArgs);
            }
        }

        [EventSubscription(EventTopicNames.OnlineStatusUpdate, ThreadOption.UserInterface)]
        public void StatusUpdateHandler(object sender, EventArgs<string> e)
        {
            statusLabel.Text = e.Data;
        }


        [EventSubscription(EventTopicNames.ParameterUpdateEvent, ThreadOption.UserInterface)]
        public void UpdateParameters(object sender, EventArgs<List<Metro.Admin.BusinessEntities.Parameter>> e)
        {
            Metro.Admin.BusinessEntities.Company company = WorkItem.Items.Get<Metro.Admin.BusinessEntities.Company>("globalCompany");
            Metro.Admin.BusinessEntities.User user = WorkItem.Items.Get<Metro.Admin.BusinessEntities.User>("UserSession");
            Metro.Admin.BusinessEntities.Status status = new Metro.Admin.BusinessEntities.Status();
            try
            {
                if (user != null && company != null)
                {
                    foreach (Metro.Admin.BusinessEntities.Parameter param in e.Data)
                    {
                        if (param.Name.Equals("openSpot"))
                            company.OpenSpot = Convert.ToDateTime(param.Value);
                        if (param.Name.Equals("closeSpot"))
                            company.CloseSpot = Convert.ToDateTime(param.Value);
                        if (param.Name.Equals("openNextDay"))
                            company.OpenNextDay = Convert.ToDateTime(param.Value);
                        if (param.Name.Equals("closeNextDay"))
                            company.CloseNextDay = Convert.ToDateTime(param.Value);
                        if (param.Name.Equals("minPrice"))
                            company.MinimalPrice = Convert.ToDecimal(param.Value);
                        if (param.Name.Equals("maxPrice"))
                            company.MaximalPrice = Convert.ToDecimal(param.Value);
                        if (param.Name.Equals("minAmount"))
                            company.MinimalAmount = Convert.ToDecimal(param.Value);
                        if (param.Name.Equals("maxAmount"))
                            company.MaximalAmount = Convert.ToDecimal(param.Value);
                        if (param.Name.Equals("taxBase"))
                            company.TaxBase = Convert.ToDecimal(param.Value);
                        if (param.Name.Equals("taxpercentage"))
                            company.TaxPercentage = Convert.ToDecimal(param.Value);
                        if (param.Name.Equals("transactionExpiration"))
                            company.TransactionDeleteExpiration = Convert.ToInt32(param.Value);
                        if (param.Name.Equals("suspend"))
                            company.PlatformSuspend = Convert.ToBoolean(param.Value);
                    }

                    if (company.PlatformSuspend)
                    {
                        CloseResponse closeResponse = new CloseResponse(CloseResponseAction);
                        this.BeginInvoke(closeResponse); 
                    }
                    else
                    {

                        status.User = user.Login;
                        status.Customer = user.CustomerName;
                        status.Market = company.GetCurrentMarket().ToString();
                        status.State = CommandNames.ConnectStatus;
                        status.Prices = company.MinimalPrice.ToString("C") + " - " + company.MaximalPrice.ToString("C");
                        status.Amounts = company.MinimalAmount.ToString("USD #,#") + " - " + company.MaximalAmount.ToString("USD #,#");

                        OnStatusUpdate(new EventArgs<Metro.Admin.BusinessEntities.Status>(status));
                    }
                }
            }
catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "UpdateParameters", MessageBoxButtons.OK, MessageBoxIcon.Warning);  
            }
        }

        private void CloseResponseAction()
        {
            try
            {
                MessageBox.Show("La plataforma ha sido suspendida", "CloseResponseAction", MessageBoxButtons.OK, MessageBoxIcon.Information);
                this.Close();
            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.Message, "CloseResponseAction", MessageBoxButtons.OK, MessageBoxIcon.Warning);  
            }
        
        }

        private void ShellForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                svcClient.UnLink();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "ShellForm_FormClosing", MessageBoxButtons.OK, MessageBoxIcon.Warning);  
            }
        }
    }
}
